package drds.configuration.common;

import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * 来源红黑联盟-isea533
 */
public class ZipUtil {

    // 测试方法：
    @SuppressWarnings("unused")
    private static void main(String[] args) throws IOException {
        /**
         * 压缩文件
         */
        File[] files = new File[]{new File("d:/1"), new File("d:/1.txt"), new File("d:/2.txt")};
        File zip = new File("d:/压缩.zip");
        ZipFiles(zip, "abc/", files);

        /**
         * 解压文件
         */
        File zipFile = new File("d:/压缩.zip");
        String path = "d:/zipfile/";
        unZipFiles(zipFile, path);
    }

    // 解压的时候，针对文件夹判断创建不存在的文件夹，对文件夹只创建，不进行解压..因为解压是针对文件的，不是文件夹，文件夹需要自己创建。
    @SuppressWarnings("unchecked")
    private static void unZipFiles(File zipFile, String descDir) throws IOException {
        if (zipFile == null) {
            throw new RuntimeException("zip文件不存在");
        }
        if (descDir == null) {
            throw new RuntimeException("解压目录不存在");
        }
        File pathFile = new File(descDir);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }
        ZipFile zip = new ZipFile(zipFile);
        for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
            String zipEntryName = entry.getName();
            try {
                InputStream in = zip.getInputStream(entry);
                String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");
                // 判断路径是否存在,不存在则创建文件路径
                File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
                if (!file.exists()) {
                    file.mkdirs();
                }
                // 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
                if (new File(outPath).isDirectory()) {
                    continue;
                }
                // 输出文件路径信息

                OutputStream out = new FileOutputStream(outPath);
                byte[] buffer = new byte[1024 * 10];
                int len;
                while ((len = in.read(buffer)) > 0) {
                    out.write(buffer, 0, len);
                }
                in.close();
                out.close();
            } catch (Exception e) {

                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 解压到指定目录
     */
    public static void unZipFiles(String zipPath, String descDir) throws IOException {
        if (!descDir.endsWith(File.separator)) {
            descDir += File.separator;
        }
        unZipFiles(new File(zipPath), descDir);
    }

    public static void ZipFiles(File zip, String path, File... srcFiles) throws IOException {
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(new FileOutputStream(zip));
            ZipUtil.ZipFiles(out, path, srcFiles);
            out.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                out = null;
                System.gc();
            }
        }
    }

    public static void ZipFiles(ZipOutputStream out, String path, File... srcFiles) {
        if (out == null) {
            throw new RuntimeException("系统不支持zip压缩，zip输出流为空");
        }
        if (path == null) {
            path = "";
        }
        path = path.replaceAll("\\*", "/");
        if (!path.endsWith("/")) {
            path += "/";
        }
        byte[] buffer = new byte[1024 * 10];
        try {
            int length = srcFiles.length;
            if (length > 0) {
                for (int i = 0; i < length; i++) {
                    if (srcFiles[i].isFile()) {
                        FileInputStream in = null;
                        try {
                            in = new FileInputStream(srcFiles[i]);
                            out.putNextEntry(new ZipEntry(path + srcFiles[i].getName()));
                            int len = 0;
                            while ((len = in.read(buffer)) > 0) {
                                out.write(buffer, 0, len);
                            }
                            out.closeEntry();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        } finally {
                            try {
                                if (in != null) {
                                    in.close();
                                }
                            } catch (Exception e) {
                                in = null;
                                System.gc();
                            }
                        }

                    } else if (srcFiles[i].isDirectory()) {
                        File[] files = srcFiles[i].listFiles();
                        String srcPath = srcFiles[i].getName();
                        srcPath = srcPath.replaceAll("\\*", "/");
                        if (!srcPath.endsWith("/")) {
                            srcPath += "/";
                        }
                        out.putNextEntry(new ZipEntry(path + srcPath));
                        ZipFiles(out, path + srcPath, files);

                    }
                }
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
